package com.pgy.general.exceptions;

import com.pgy.general.result.RetCode;
import com.pgy.general.result.RetResponse;
import com.pgy.general.result.RetResult;
import io.jsonwebtoken.MalformedJwtException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;

/**
 * @Auther:superChao
 * @Date: 2021/03/19/9:02
 * @Version:2.0.0
 */
@ControllerAdvice
@ResponseBody
public class GloablExceptionHandler {
    private static Logger logger = LoggerFactory.getLogger(GloablExceptionHandler.class);
    @ExceptionHandler(Exception.class)
    public RetResult handleException(Exception e) {
        String msg = "";
        if (e instanceof generalRuntimeException){
            msg=e.getMessage();
        }else {
            if (e instanceof LoginRuntimeException||e instanceof MalformedJwtException){
                return RetResponse.makeRsp(RetCode.UNAUTHORIZED,"登录过期，请重新登录！");
            }
            msg = "系统繁忙,请稍后再试";
        }
        return RetResponse.serverErrRsp(msg);
    }
    /**
     * 方法参数校验
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public RetResult handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        logger.error("参数验证错误："+e.getMessage());
        return RetResponse.makeRsp(RetCode.PARAM_FAIL_CODE,e.getBindingResult().getFieldError().getDefaultMessage());
    }

    @ExceptionHandler(BindException.class)
    public RetResult handleBindException(BindException e) {
        logger.error("参数验证错误："+e.getMessage());
        return RetResponse.makeRsp(RetCode.PARAM_FAIL_CODE,e.getBindingResult().getFieldError().getDefaultMessage());
    }

    /**
     * 验证异常
     *
     * ValidationException
     */
    @ExceptionHandler(ValidationException.class)
    public RetResult handleValidationException(ValidationException e) {
        logger.error("验证异常："+e.getMessage());
        return RetResponse.makeRsp(RetCode.PARAM_FAIL_CODE,"数据格式错误请检查您的数据！");
    }
    //数据格式异常

    /**
     * 违反约束异常
     * ConstraintViolationException
     */
    @ExceptionHandler(DataIntegrityViolationException.class)
    public RetResult handleDataIntegrityViolationException(DataIntegrityViolationException e){
        logger.error("外键删除异常："+e.getMessage());
        return RetResponse.makeRsp(RetCode.PARAM_FAIL_CODE,"该信息有关联内容，请删除相关内容后再次删除该条信息");
    }
    @ExceptionHandler(ConstraintViolationException.class)
    public RetResult handleConstraintViolationException(ConstraintViolationException e) {
        logger.error("违反约束异常："+e.getMessage());
        return RetResponse.makeRsp(RetCode.PARAM_FAIL_CODE,e.getMessage());
    }
    //数据库插入数据异常
    @ExceptionHandler(DuplicateKeyException.class)
    public RetResult handleDuplicateKeyException(DuplicateKeyException e) {
        logger.error("数据库插入数据异常:"+e.getMessage());
        return RetResponse.makeRsp(RetCode.PARAM_FAIL_CODE,"数据重复，请检查数据后重新插入！");
    }


    @ExceptionHandler(value =NullPointerException.class)
    @ResponseBody
    public RetResult exceptionHandler(HttpServletRequest req, NullPointerException e){
        logger.error("查询了不存在数据，发生空指针异常！:",e+e.getMessage()+e.toString());
        return RetResponse.makeRsp(RetCode.PARAM_FAIL_CODE,"该数据不存在！");
    }

}
